/*
 * Copyright (c) zhg2yqq.com Corp.
 * All Rights Reserved.
 */
package com.zhg2yqq.wheels.security.multi;

import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
import org.springframework.security.config.annotation.web.configurers.AbstractAuthenticationFilterConfigurer;
import org.springframework.security.web.authentication.ForwardAuthenticationFailureHandler;
import org.springframework.security.web.authentication.ForwardAuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;

/**
 * @author zhg2yqq, 2023年3月17日
 * @version zhg2yqq v1.0
 */
public final class CustomFormLoginConfigurer<H extends HttpSecurityBuilder<H>> extends
        AbstractAuthenticationFilterConfigurer<H, CustomFormLoginConfigurer<H>, CustomAuthenticationFilter> {
    private CustomAuthenticationProperties properties;

    public CustomFormLoginConfigurer(CustomAuthenticationProperties properties) {
        super(new CustomAuthenticationFilter(), null);
        this.properties = properties;
    }

    @Override
    public CustomFormLoginConfigurer<H> loginPage(String loginPage) {
        return super.loginPage(loginPage);
    }

    public CustomFormLoginConfigurer<H> usernameParameter(String usernameParameter) {
        getAuthenticationFilter().setUsernameParameter(usernameParameter);
        return this;
    }

    public CustomFormLoginConfigurer<H> passwordParameter(String passwordParameter) {
        getAuthenticationFilter().setPasswordParameter(passwordParameter);
        return this;
    }

    public CustomFormLoginConfigurer<H> typeParameter(String typeParameter) {
        getAuthenticationFilter().setTypeParameter(typeParameter);
        return this;
    }

    public CustomFormLoginConfigurer<H> keyParameter(String keyParameter) {
        getAuthenticationFilter().setKeyParameter(keyParameter);
        return this;
    }

    public CustomFormLoginConfigurer<H> codeParameter(String codeParameter) {
        getAuthenticationFilter().setCodeParameter(codeParameter);
        return this;
    }

    public CustomFormLoginConfigurer<H> tokenProducer(AuthenticationTokenProducer tokenProducer) {
        getAuthenticationFilter().setTokenProducer(tokenProducer);
        properties.setTypes(tokenProducer.getFactories().keySet());
        return this;
    }

    public CustomFormLoginConfigurer<H> addTokenFactory(IAuthenticationTokenFactory factory) {
        getAuthenticationFilter().getTokenProducer().addAuthenticationTokenFactory(factory);
        properties.getTypes().add(factory.type());
        return this;
    }

    public CustomFormLoginConfigurer<H> failureForwardUrl(String forwardUrl) {
        failureHandler(new ForwardAuthenticationFailureHandler(forwardUrl));
        return this;
    }

    public CustomFormLoginConfigurer<H> successForwardUrl(String forwardUrl) {
        successHandler(new ForwardAuthenticationSuccessHandler(forwardUrl));
        return this;
    }

    @Override
    public void init(H http) throws Exception {
        super.init(http);
        initDefaultLoginFilter(http);
    }

    @Override
    protected RequestMatcher createLoginProcessingUrlMatcher(String loginProcessingUrl) {
        return new AntPathRequestMatcher(loginProcessingUrl, "POST");
    }

//    private String getUsernameParameter() {
//        return getAuthenticationFilter().getUsernameParameter();
//    }
//
//    private String getPasswordParameter() {
//        return getAuthenticationFilter().getPasswordParameter();
//    }

    private void initDefaultLoginFilter(H http) {
        http.addFilterBefore(getAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
    }
}
